package org.apache.geronimo.daytrader.javaee6.web;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.lang.management.*;

/**
 * 
 */
/**
 * @author rajat
 * This class is a singleton logger
 */
public class oSingletonLogger {

    private static oSingletonLogger instance;
    private static int SAMPLE_TIMER = 30; //IN Seconds
    private Vector<String> LogHistory;
    private static int arrivalcounter;
    private static int departcounter;
    private static int queuecounter;
    private Timer timer;
    private Object lock1 = new Object(); // used to lock
    private static ThreadMXBean threadbean = ManagementFactory.getThreadMXBean();
    private static MemoryMXBean memorybean = ManagementFactory.getMemoryMXBean();

    private oSingletonLogger() {
        this.timer = new Timer();
        this.LogHistory = new Vector<String>();
        timer.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                //do something here
                oSingletonLogger.getInstance().dumpLogs();
            }
        }, SAMPLE_TIMER * 1000, SAMPLE_TIMER * 1000); // Will start with a delay of 30 seconds

    }

    public static synchronized oSingletonLogger getInstance() {
        if (instance == null) {
            instance = new oSingletonLogger();
        }
        return instance;
    }

    public void dumpLogs() {
        // synchronized(lock1)
//		{

        System.out.println("Time's up!");
        FileOutputStream raf = null;
        try {
            raf = new FileOutputStream("serverResponseTime.log", true);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return;
        }
        FileChannel channel = raf.getChannel();
        FileLock lock = null;
        PrintStream p = null;
        try {
            lock = channel.lock();
            System.out.println("Size is: " + LogHistory.size());
            //  PrintStream p = new PrintStream(new BufferedOutputStream(raf));
            p = new PrintStream(new BufferedOutputStream(raf));
            long currTime = System.currentTimeMillis();

            //@Abhishek:Thread usage

            int currthreadCount = threadbean.getThreadCount();

            int peakThreadCount = threadbean.getPeakThreadCount();

            int daemonThreads = threadbean.getDaemonThreadCount();



            //@Abhishek:reset peak count

            threadbean.resetPeakThreadCount();



            //@Abhishek:MemoryUsage

            String HeapMemory = memorybean.getHeapMemoryUsage().toString();
            //         String NonHeapMemory=memorybean.getNonHeapMemoryUsage().toString();

            StringBuffer newEntry = new StringBuffer();

            // newEntry.append(currTime+":samplednumSrvReqCount=:"+queuecounter+":sampledarrivalCount=:"+arrivalcounter+":sampleddepartCount=:"+departcounter

            //                         +":PeakThreads=:"+peakThreadCount+":currentThreads=:"+currthreadCount+":daemonThreads=:"+daemonThreads+":HeapMemory=:"+HeapMemory);

            //  p.println(newEntry);

            System.out.println(currTime + ":samplednumSrvReqCount=:" + queuecounter + ":sampledarrivalCount=:" + arrivalcounter + ":sampleddepartCount=:" + departcounter
                    + ":PeakThreads=:" + peakThreadCount + ":currentThreads=:" + currthreadCount + ":daemonThreads=:" + daemonThreads + ":HeapMemory=:" + HeapMemory);

            synchronized (lock1) {
                for (String Entry : LogHistory) {
                    p.println(Entry);
                    //System.out.println(Entry);
                    //System.out.println("Entry has some value");
                }
                //p.close();		
                LogHistory.clear();
                arrivalcounter = 0;
                departcounter = 0;
            }
            //    catch (FileNotFoundException e)
            //	{
            // TODO Auto-generated catch block
            //      e.printStackTrace();
//        return;
//      }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return;
        } finally {
            if (lock != null) {
                try {
                    lock.release();
                    p.close();
                    //	 raf.close();

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
        // }
    }

    public void insertLog(String message) {
        synchronized (lock1) {
            this.LogHistory.add(message);
        }
    }

    public int incrementCounter() {
        synchronized (lock1) {
            this.arrivalcounter += 1;
            this.queuecounter += 1;
            return this.arrivalcounter;
        }
    }

    public int decrementCounter() {
        synchronized (lock1) {
            this.departcounter += 1;
            this.queuecounter -= 1;
            return this.departcounter;
        }
    }

    public int getQueueCounter() {
        synchronized (lock1) {
            return this.queuecounter;
        }
    }
}
